package org.lgiavedoni.android.franq.util.phone.wifi;

import java.util.ArrayList;
import java.util.List;

import org.lgiavedoni.android.franq.core.bean.WifiNetwork;
import org.lgiavedoni.android.franq.service.log.Logger;
import org.lgiavedoni.android.franq.service.phone.ContextService;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;

import com.google.inject.Singleton;

@Singleton
public class WifiManagerPhone implements WifiManager {

	private android.net.wifi.WifiManager wifi;

	public WifiManagerPhone() {
		try {
			// Setup WiFi
			if (ContextService.inst.isApplicationContextLoaded()) {
				wifi = (android.net.wifi.WifiManager) ContextService.inst.getApplicationContext().getSystemService(ContextService.inst.getApplicationContext().WIFI_SERVICE);
			}
		} catch (Exception ex) {
			Logger.inst.error(ex);
		}
	}

	public List<ScanResult> listWifiNetworks() {
		final List<ScanResult> result = new ArrayList<ScanResult>();
		if (!ContextService.inst.isApplicationContextLoaded())
			return new ArrayList<ScanResult>();
		try {
			result.clear();

			// Register Broadcast Receiver
			BroadcastReceiver receiver = new BroadcastReceiver() {
				int wait = 4;

				@Override
				public void onReceive(Context c, Intent intent) {
					if (wifi.getScanResults() != null)
						result.addAll(wifi.getScanResults());
					if (result.size() > 0 || wait == 0) {
						synchronized (result) {
							result.notifyAll();
						}
					} else {
						wait--;
						wifi.startScan();
					}
				}

			};

			ContextService.inst.getApplicationContext().registerReceiver(receiver, new IntentFilter(android.net.wifi.WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));

			boolean enabledBefore = wifi.isWifiEnabled();
			if (!enabledBefore) {
				turnON();
			}
			if (wifi.getConnectionInfo() != null) {
				wifi.startScan();
			}
			synchronized (result) {
				if (result.size() == 0)
					result.wait();
			}

			if (!enabledBefore) {
				turnOFF();
			}
			ContextService.inst.getApplicationContext().unregisterReceiver(receiver);

		} catch (InterruptedException ex) {
			Logger.inst.error(ex);
		}
		return result;
	}

	public List<WifiNetwork> listWifiNetworksBSSID() {
		List<WifiNetwork> l = new ArrayList<WifiNetwork>();
		for (ScanResult sr : listWifiNetworks()) {
			l.add(new WifiNetwork(sr.SSID, sr.BSSID));
		}
		return l;
	}

	public void turnON() {
		if (wifi != null) {
			wifi.setWifiEnabled(true);
		} else
			Logger.inst.warning("WifiUtil.turnON FAIL. Not manager available");
	}

	public void turnOFF() {
		if (wifi != null) {
			if (wifi.getConnectionInfo() != null)
				wifi.disconnect();
			wifi.setWifiEnabled(false);
		} else
			Logger.inst.warning("WifiUtil.turnON FAIL. Not manager available");
	}

}
